package net.funtip.jdbc.driver;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Properties;
import java.util.logging.Logger;


public class LogDriver implements Driver {

	private Logger log = Logger.getLogger(this.getClass().getName());
	
	private static final String URL_PREFIX = "jdbcStats:";
	public static final String PROPERTY_FILENAME = "/jdbcStats.properties";
	public static final String REAL_DRIVER_CLASS = "real_driver_class";
	public static final String REAL_DRIVER_DATASOURCE = "real_driver_datasource";
	
	public static final String DEFAULT_REAL_DRIVER_CLASS = "com.ibm.db2.jcc.DB2Driver";
	
	private Driver realDriver = null;
	private String realDriverClass = null;
	
	static {
		try {
			DriverManager.registerDriver(new LogDriver());
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage(), e);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		} catch (InstantiationException e) {
			throw new RuntimeException(e.getMessage(), e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e.getMessage(), e);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
 
	public LogDriver() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
		loadProperties();
		log.finest("loading real jdbc driver: "+realDriverClass);
		realDriver = (Driver) Class.forName(realDriverClass).newInstance();
	}
	
	private void loadProperties() {
		Properties prop = new Properties();
		try {
			InputStream in = this.getClass().getResourceAsStream(PROPERTY_FILENAME);
			prop.load(in);
			in.close();
			realDriverClass = prop.getProperty(REAL_DRIVER_CLASS);
		} catch (Throwable e) {
			log.finest("Error loading real driver class, using default:"+DEFAULT_REAL_DRIVER_CLASS);
			realDriverClass = DEFAULT_REAL_DRIVER_CLASS;
		}
	}
	
	public boolean acceptsURL(String url) throws SQLException {
		log.info("acceptURL: "+url);
		return url.startsWith(URL_PREFIX);
	}

	public Connection connect(String url, Properties info) throws SQLException {
		log.finest("connecting to database "+url+" with properties "+info);
		String realUrl = getRealUrl(url);
		log.finest("redirecting connection to: "+realUrl);
		Connection conn = null;
		conn = realDriver.connect(realUrl, info);
		log.finest("connected.");
		return new FTConnection(conn);
	}

	public static String getRealUrl(String url) {
		return (url.startsWith(URL_PREFIX)? url.substring(URL_PREFIX.length()):null);
	}

	public int getMajorVersion() {
		return realDriver.getMajorVersion();
	}

	public int getMinorVersion() {
		return realDriver.getMinorVersion();
	}

	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
		return realDriver.getPropertyInfo(url, info);
	}

	public boolean jdbcCompliant() {
		return realDriver.jdbcCompliant();
	}

	public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO implement when using JDK 1.7
		return null;
	}

}
